package com.hmall.item.web;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmall.common.Constant.ItemConstant;
import com.hmall.common.Constant.RabbitMQConstant;
import com.hmall.common.Constant.ResultConstant;
import com.hmall.common.dto.ItemDTO;
import com.hmall.common.dto.PageDTO;
import com.hmall.common.result.Result;
import com.hmall.common.utils.BaseThreadLocal;
import com.hmall.common.vo.ItemPageVo;
import com.hmall.common.vo.ItemVo;
import com.hmall.item.mapper.ItemMapper;
import com.hmall.item.pojo.Item;
import com.hmall.item.service.IItemService;
import org.apache.ibatis.annotations.Param;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("item")
public class ItemController {
    
    @Autowired
    private IItemService itemService;
    @Autowired
    ItemMapper itemMapper;
    @Autowired
    RabbitTemplate rabbitTemplate;
    
    /**
     * 分页查询商品
     *
     * @param currentPage
     * @param pageSize
     * @return
     */
    @GetMapping("/list")
    public PageDTO list(@RequestParam("page") Long currentPage, @RequestParam("size") Long pageSize) {
        //创建分页查询返回对象
        PageDTO<ItemPageVo> pageDTO = new PageDTO<>();
        //创建分页对象
        Page<Item> page = new Page<>(currentPage, pageSize);
        //分页查询，获取结果
        Page<Item> pageList = itemService.page(page);
        //结果判空
        if (pageList == null || pageList.getTotal() == 0) {
            return pageDTO;
        }
        //使用stream流将分页查询对象转换为返回的vo对象
        List<ItemPageVo> itemPageVos = pageList.getRecords().stream().map(item -> {
            ItemPageVo itemPageVo = new ItemPageVo();
            //将查询结果拷贝至返回对象内
            BeanUtils.copyProperties(item, itemPageVo);
            //处理id,防止long类型返回前端数值溢出问题
            itemPageVo.setId(item.getId().toString());
            return itemPageVo;
        }).collect(Collectors.toList());
        //设置总数
        pageDTO.setTotal(pageList.getTotal());
        //设置分页查询结果集合
        pageDTO.setList(itemPageVos);
        return pageDTO;
    }
    
    /**
     * 根据id查询商品
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public ItemVo findById(@PathVariable("id") Long id) {
        //根据id查询数据
        Item item = itemService.getById(id);
        //创建返回对象
        ItemVo itemVo = new ItemVo();
        //判空
        if (item == null) {
            return itemVo;
        }
        //将查询结果拷贝至返回对象内
        BeanUtils.copyProperties(item, itemVo);
        //处理id,防止long类型返回前端数值溢出问题
        itemVo.setId(item.getId().toString());
        return itemVo;
    }
    
    /**
     * 新增商品
     *
     * @param itemDTO
     */
    @PostMapping
    public Result saveGoods(@RequestBody ItemDTO itemDTO) {
        //创建Item实体类对象
        Item item = new Item();
        //判空
        if (itemDTO == null) {
            return Result.error(ResultConstant.SAVE_EXCEPTION);
        }
        //将DTO内数据拷贝至实体类内
        BeanUtils.copyProperties(itemDTO, item);
        //添加商品至数据库,返回主键id
        itemMapper.insert(item);
        //向mq发送消息，新增es商品信息
        rabbitTemplate.convertAndSend(RabbitMQConstant.EXCHANGE_NAME, RabbitMQConstant.QUEUE_INSERT_KEY, item.getId().toString());
        return Result.success();
    }
    
    /**
     * 商品下架与上架
     *
     * @param id
     * @param status
     */
    @PutMapping("/status/{id}/{status}")
    public Result upAndDownGoods(@PathVariable("id") Long id, @PathVariable("status") Integer status) {
        //根据id查询数据，并进行判断
        Item item = itemService.getById(id);
        if (item == null || item.getStatus().equals(status)) {
            //当查询结果为空或修改状态与当前状态相同时，返回失败信息
            return Result.error(ResultConstant.UPDATE_EXCEPTION);
        }
        //设置状态
        item.setStatus(status);
        //更新商品状态
        itemService.updateById(item);
        //向mq发送消息，下架与上架es商品
        if(status == ItemConstant.ITEM_UP_STATUS){
            //上架商品至es
            rabbitTemplate.convertAndSend(RabbitMQConstant.EXCHANGE_NAME, RabbitMQConstant.QUEUE_INSERT_KEY, item.getId().toString());
        }else {
            //下架es商品
            rabbitTemplate.convertAndSend(RabbitMQConstant.EXCHANGE_NAME, RabbitMQConstant.QUEUE_DELETE_KEY, item.getId().toString());
        }
        return Result.success();
    }
    
    /**
     * 根据id修改商品
     *
     * @param itemDTO
     */
    @PutMapping
    public Result updateGoods(@RequestBody ItemDTO itemDTO) {
        //判空
        if (itemDTO == null) {
            return Result.error(ResultConstant.UPDATE_EXCEPTION);
        }
        //根据获取商品数据
        Item itemById = itemService.getById(itemDTO.getId());
        //判空和判断状态是否为 1 上架
        if (itemById != null && itemById.getStatus() != ItemConstant.ITEM_UP_STATUS) {
            Item item = new Item();
            BeanUtils.copyProperties(itemDTO, item);
            itemService.updateById(item);
            //向mq发送消息，修改es商品信息
            rabbitTemplate.convertAndSend(RabbitMQConstant.EXCHANGE_NAME, RabbitMQConstant.QUEUE_INSERT_KEY, item.getId().toString());
            return Result.success();
        }
        return Result.error(ResultConstant.UPDATE_EXCEPTION);
    }
    
    /**
     * 根据id删除商品
     *
     * @param id
     */
    @DeleteMapping("/{id}")
    public Result deleteGoods(@PathVariable("id") Long id) {
        Item itemById = itemService.getById(id);
        //判空和判断状态是否为 1 上架
        if (itemById != null && itemById.getStatus() != ItemConstant.ITEM_UP_STATUS) {
            itemService.removeById(id);
            //向mq发送消息，删除es商品信息
            rabbitTemplate.convertAndSend(RabbitMQConstant.EXCHANGE_NAME, RabbitMQConstant.QUEUE_DELETE_KEY, id.toString());
            return Result.success();
        }
        return Result.error(ResultConstant.DELETE_EXCEPTION);
    }
    
    /**
     * 削减库存接口
     *
     * @param id
     * @param num
     */
    @GetMapping("/reduceStock/{id}/{num}")
    public void reduceStock(@PathVariable("id") Long id, @PathVariable("num") Integer num) {
        //根据id查询商品
        Item item = itemService.getById(id);
        //如果查询结果为空或库存小于等于0则抛出异常
        if (item == null || item.getStock() <= 0) {
            throw new RuntimeException("削减库存失败");
        }
        //削减库存
        item.setStock(item.getStock() - num);
        //更新数据
        itemService.updateById(item);
    }
    
    /**
     * 恢复库存接口
     *
     * @param id
     * @param num
     */
    @GetMapping("/restoreStock/{id}/{num}")
    public void restoreStock(@PathVariable("id") Long id, @PathVariable("num") Integer num) {
        //根据id查询商品
        Item item = itemService.getById(id);
        //如果查询结果为空则抛出异常
        if (item == null) {
            throw new RuntimeException("恢复库存失败");
        }
        //恢复库存
        item.setStock(item.getStock() + num);
        //更新数据
        itemService.updateById(item);
    }
    
    @GetMapping("/page")
    public List<Item> findAllGoods(@RequestParam("page") Long currentPage, @RequestParam("size") Long pageSize) {
        //创建分页对象
        Page<Item> page = new Page<>(currentPage, pageSize);
        //分页查询，获取结果
        Page<Item> pageList = itemService.page(page);
        return pageList.getRecords();
    }
}
